#pragma once
#include <iostream>
#include "Transaction.h"
#include "Action.h"
#include <list>
#include <stack>
#include <string>
#include "History.h"
#include <time.h>
#include "Income.h"
#include "Transfer.h"

//@author A0091791X
class Manager
{
private:
	static bool _existed;
	static Manager* ONE;
	list<Transaction>* _recordAddr;
	list<string>* _catAddr;
	list<string>* _accAddr;
	list<double>* _accDepAddr;
	stack<Action> _action;
	int* _SN;
	//constructor
	Manager(list<Transaction>* recordAddr, list<string>* catAddr, list<string>* accAddr, list<double>* accDepAddr, int* SN);
public:
	
	~Manager();
	
	//Singelton getter
	static Manager* getOne(list<Transaction>*, list<string>*, list<string>*, list<double>*, int*);
	static Manager* get();
	//getter
	list<Transaction>* getRecordAddr();
	list<string>* getAccAddr();
	list<string>* getCatAddr();
	list<double>* getAccDep();
	int* getSNAddr();
	stack<Action>* getActionStack();
	int getActionStackSize();
	list<double>::iterator getAccDepIter(string);
	list<Transaction>::iterator findTransaction(int);
	list<string>::iterator findAccount(string);
	list<string>::iterator findCategory(string);
	
	//@author A0066758M
	//add/delete transaction
	Transaction* addTransaction(Transaction*);
	bool editTransaction(int, string, dateTime, double);
	bool editTransaction(int, string, string, dateTime, double); 
	bool editTransaction(int, Transaction T);
	bool delTransaction(list<Transaction>::iterator);
	bool delTransaction(Transaction*);

	//add/edit/delete account
	bool addAccount(string, double);
	bool editAccountName(string, string);
	bool delAccount(string);

	//add/edit/delete category
	bool addCategory(string);
	bool editCategory(string, string);
	bool delCategory(string);
	
	//@author A0090982W
	//consolidating functions 
	History AllTransaction();
	History currMonth(int,int);
	History today(int,int,int);
	double getAccBalance(string);
	double getTotInitialDep();
	double getTotBalance();
	struct dateTime NOW();
	bool enoughBal(string, double);

	//@author A0091791X
	void incrementSN();
	void changeAccName(string, string);
	void changeCatName(string, string);
	bool checkDouble(string);
	bool checkDP(string);
	
	void pushUndo(int, Transaction);
	void performUndo();
	void clearActionStack();
};

